package com.custom.action.joiner;

import com.custom.action.condition.ConditionSplicer;
import com.custom.action.joiner.interfaces.DoSomething;
import com.custom.action.util.DbUtil;
import com.custom.comm.enums.DbJoinStyle;
import com.custom.comm.enums.DbSymbol;
import com.custom.comm.utils.Constants;
import com.custom.comm.utils.JudgeUtil;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * SQl条件装配
 * @author Xiao-Bai
 * @since 2023/4/30 18:14
 */
@SuppressWarnings("unchecked")
public abstract class JoinConditionAssembly<T, Children> extends JoinConditionWrapper<T> implements ConditionSplicer<Children> {


    /**
     * 装配方法
     */
    protected Children addSqlAssembly(boolean condition, DoSomething something) {
        if (condition) {
            collectWhereCondition(something);
        }
        return childrenClass;
    }


    /**
     * 拼接大条件
     * @param condition 是否拼接
     * @param spliceStatus true: 条件前缀为AND, false: 条件前缀为OR
     * @param wrapper 拼接的条件
     */
    protected Children spliceCondition(boolean condition, boolean spliceStatus, JoinConditionWrapper<T> wrapper) {
        if(condition && Objects.nonNull(wrapper)) {
            this.mergeConditionWrapper(spliceStatus, wrapper);
        }
        return childrenClass;
    }


    /**
     * 合并新的条件构造器
     */
    protected void mergeConditionWrapper(boolean spliceStatus, JoinConditionWrapper<T> wrapper) {

        // 1. 合并查询列-select
        if (JudgeUtil.isNotEmpty(wrapper.getSelectColumnList())) {
            getSelectColumnList().addAll(wrapper.getSelectColumnList());
        }
        if (JudgeUtil.isNotEmpty(wrapper.getSelectAllColumnList())) {
            getSelectAllColumnList().addAll(wrapper.getSelectAllColumnList());
        }

        // 2. 合并添加一般条件-condition
        if (JudgeUtil.isNotEmpty(wrapper.getConditionList())) {
            addSqlAssembly(true, () -> {
                DbSymbol prefix = spliceStatus ? DbSymbol.AND : DbSymbol.OR;
                String maxCondition = wrapper.getConditionList().stream()
                        .map(DoSomething::getSomething)
                        .collect(Collectors.joining());
                addParams(wrapper.getParamValues());
                return DbUtil.appendMaxCondition(prefix, maxCondition);
            });
        }

        // 3. 合并分组-group by
        if (JudgeUtil.isNotEmpty(wrapper.getGroupByList())) {
            getGroupByList().addAll(wrapper.getGroupByList());
        }

        // 4. 合并-having
        if (JudgeUtil.isNotEmpty(wrapper.getHavingList())) {
            getHavingList().addAll(wrapper.getHavingList());
        }

        // 5. 合并排序字段-orderBy
        if (JudgeUtil.isNotEmpty(wrapper.getOrderByList())) {
            getOrderByList().addAll(wrapper.getOrderByList());
        }

    }


    /**
     * 合并消费类型的条件
     */
    protected Children mergeConsumerCondition(boolean condition, boolean spliceType, Consumer<Children> consumer) {
        if (condition) {
            Children instance = getInstance();
            consumer.accept(instance);
            return spliceCondition(true, spliceType, (JoinConditionWrapper<T>) instance);
        }
        return childrenClass;
    }

    /**
     * 添加自定义的条件，该条件只允许在where之后, group by 之前
     */
    public Children addCustomizeSql(boolean condition, String customizeSql, Object... params) {
        collectCustomizeCondition(condition, customizeSql, params);
        return childrenClass;
    }

    /**
     * 添加自定义的条件，该条件只允许在where之后, group by 之前
     */
    public Children addCustomizeSql(String customizeSql, Object... params) {
        return addCustomizeSql(true, customizeSql, params);
    }


    /**
     * 子类的实例
     */
    protected abstract Children getInstance();
    protected Children childrenClass = (Children) this;
}
